package com.qingxin.sys.verifier.rules;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;

import com.qingxin.sys.verifier.FormMap;
import com.qingxin.sys.verifier.VerifyMsg;
import com.qingxin.sys.verifier.VerifyRule;

/**
 * 字段比较验证
 * @author Administrator
 *
 */
public class CompareRule extends VerifyRule {

	private String type;//string/number/date/datetime
	private String destid;
	private String destname;
	private String destlabel;
	private String operateor;//eq等于、ne不等于、gt大于、ge大于等于、lt小于、le小于等于
	
	
	public CompareRule() {
		this.type = "string";
		this.destid = "";
		this.destname = "";
		this.operateor = "eq";
	}
	
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public VerifyMsg isValid(String id, String name, String label, FormMap formMap) {
		String value = formMap.getParameter(name);
		String destVal = formMap.getParameter(destname);
		Comparable _val = value;
		Comparable _destVal = destVal;
		if("number".equalsIgnoreCase(type)){
			if(!isEmpty(value)){
				try {
					_val = new BigDecimal(value);
				} catch (Exception e) {}
			}
			if(!isEmpty(destVal)){
				try {
					_destVal = new BigDecimal(destVal);
				} catch (Exception e) {}
			}
		}else if("date".equalsIgnoreCase(type) || "datetime".equalsIgnoreCase(type)){
			SimpleDateFormat sdf = null;
			if ("date".equalsIgnoreCase(type)) {
				sdf = new SimpleDateFormat("yyyy-MM-dd");
			}else{
				sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			}
			if(!isEmpty(value)){
				try {
					_val = sdf.parse(value);
				} catch (Exception e) {}
			}
			if(!isEmpty(destVal)){
				try {
					_destVal = sdf.parse(destVal);
				} catch (Exception e) {}
			}
		}
		if(_val == null || _destVal == null){
			return null;//没有值时忽略该规则
		}
		boolean pass = false;
		if("eq".equalsIgnoreCase(operateor)){
			pass = _val.compareTo(_destVal) == 0;
		}else if("ne".equalsIgnoreCase(operateor)){
			pass = _val.compareTo(_destVal) != 0;
		}else if("gt".equalsIgnoreCase(operateor)){
			pass = _val.compareTo(_destVal) > 0;
		}else if("ge".equalsIgnoreCase(operateor)){
			pass = _val.compareTo(_destVal) >= 0;
		}else if("lt".equalsIgnoreCase(operateor)){
			pass = _val.compareTo(_destVal) < 0;
		}else if("le".equalsIgnoreCase(operateor)){
			pass = _val.compareTo(_destVal) <= 0;
		}
		
		if(!pass){
			String message = createMessage(null, "{name}", label, "{label}", label, "{dest}", destlabel);
			return new VerifyMsg(id, name, label, this.getClass().getSimpleName(), message);
		}
		
		return null;
	}

	
	
	@Override
	public Map<String, Object> getRuleCfg(String name, String label) {
		if(isEmpty(getDestid())){
			return null;
		}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("rtype", "compare");
		if(!"string".equalsIgnoreCase(type)){
			map.put("type", type);
		}
		map.put("dest", getDestid());
		if(!"eq".equalsIgnoreCase(operateor)){
			map.put("operateor", operateor);
		}
		
		String errormsg = createMessage(null, "{name}", label, "{label}", label, "{dest}", destlabel);
		if(!isEmpty(errormsg)){
			map.put("error", errormsg);
		}
		
		return map;
	}
	
	
	@Override
	protected void handleRuleArg(String arg) {
		super.handleRuleArg(arg);
		if("n".equals(arg)){
			setType("number");
		}else if("d".equals(arg)){
			setType("date");
		}else if("t".equals(arg)){
			setType("datetime");
		}else if("s".equals(arg)){
			setType("string");
		}else if("_eq_".equals(arg) || "_ne_".equals(arg) || "_gt_".equals(arg)
				|| "_ge_".equals(arg) || "_lt_".equals(arg) || "_le_".equals(arg)){
			setOperateor(arg.substring(1, 3));
		}
	}
	
	
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public String getDestid() {
		if(isEmpty(destid)){
			return destname;
		}
		return destid;
	}
	public void setDestid(String destid) {
		this.destid = destid;
	}
	public String getDestname() {
		return destname;
	}
	public void setDestname(String destname) {
		this.destname = destname;
	}
	public String getDestlabel() {
		return destlabel;
	}
	public void setDestlabel(String destlabel) {
		this.destlabel = destlabel;
	}
	public String getOperateor() {
		return operateor;
	}
	public void setOperateor(String operateor) {
		this.operateor = operateor;
	}
	
	
	
}
